package hku.cs.lunuo.cost;

import hku.cs.lunuo.Global;
import hku.cs.lunuo.rank.StmtResult;
import hku.cs.lunuo.rank.StmtResultUnit;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author xj One approach to evaluate the effectiveness of the
 *         fault-localization technique. This metric, we call expense is
 *         computed by the following equation. Expense = (rank of faulty
 *         statement) /(number of executable statements) *100%
 */

public class Cost {
	List<Error> error = new ArrayList<Error>();
	File errfile = null;
	
	public Cost(File err) {
		this.errfile = err;
	}

	public void getExpense(StmtResult result) {
		float expense = 0;
		try {
			getFaultyStmtLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (error.size() == 0) {
			System.out.println("Warning! You haven't set the error line.");
			return;
		}
//		else{
//			System.out.println(error.toString());
//		}

		Iterator it = result.iterator();
		int lines = result.getSize();
			while(it.hasNext()) {
				StmtResultUnit sru = (StmtResultUnit)it.next();
				Error r = new Error(sru.getKlassName(), sru.getLn());
				if (error.contains(r)) {
					expense = computeExpense(sru.getRank(), lines);
					 System.out.print("method=" + Global.v().modelName +
					 " expense="
					 + expense + " rank=" + sru.getRank() + " lines="
					 + lines+" faultRatio=" + Global.v().faultRatio);
//					System.out.print(expense+" ");
					return;
				}
			}
			System.out.print("method=" + Global.v().modelName+" expense=-1 rank=-1 lines="+ lines
					+" faultRatio="+ Global.v().faultRatio);
			
//if print this line, it means "Can't find error line", so the error line in FaultSeeds.h may wrong

	}

	public void getFaultyStmtLine() throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				new FileInputStream(errfile)));
		String line = reader.readLine();
		while (line != null) {
			String info = line.split("//")[1];
			if (info.split(" ").length == 2) {
				String klassName = info.split(" ")[0];
				String lines = info.split(" ")[1];
				for (String l : lines.split(",")) {
					String[] ls = l.split("~");
					if (ls.length == 1)
						error.add(new Error(klassName, Integer.parseInt(l)));
					else if (ls.length == 2)
						for (int i = Integer.parseInt(ls[0]); i < Integer
								.parseInt(ls[1]) + 1; i++)
							error.add(new Error(klassName, i));
				}
			}
			line = reader.readLine();
		}
		reader.close();
	}

	public float computeExpense(int rank, int total) {
		return (float) rank / total;
	}
}
